#pragma once

//Bit flags are used for all block information
// 8 7 6 5 4 3 2 1
// 0 0 0 0 0 0 0 0
// To set 1 : (1)
// 2 : (1<<1)
// 3 : (1<<2)
// ...
// To set 1 and 2 : (1|1<<1)

//Since there are 4 bytes in an int
// 1 2 3 4
// 1 is currently a buffer space to keep data allignment
// 2 is used to hold the block type
// 3 is used to hold the block trait
// 4 is used to hold the block trait power

//Since almost all bytes are being used
//do not flip bits without checking
// Eg. BlockTypeX (1|1<<4|1<<9)
//	this would flip a bit in the trait byte also
//  which would confuse the block

//Also since placement of the bits is important a bit shift
// can never be called on the block data itself

/** ASSET ID **\
\**	Bit #1	 **/
/*#1 0000-0000  #2 0000-0000  #3 0000-0000  #4 0000-0000 
         ^
		*/
//Bit 1
//1 = first bit
//1<<7 = last bit

//Doesn't need any defined statements. They will be figured out by graphics and handed to the world
// the world will interpret them and hand them to the blocks.
#define BLOCK_ASSET_ID_MASK FIRST_BYTE_MASK



/** BLOCK TYPES **\
\**	Bit #2	    **/
/*#1 0000-0000  #2 0000-0000  #3 0000-0000  #4 0000-0000
					   ^*/
//Bit 2
//1<<8 = first bit
//1<<15 = last bit
//Block Types

//7 spaces set aside for special blocks
enum eSpecialTypes {
	//Space 1
	BLOCK_TYPE_AIR		= (1<<8),						// 0000-0001

	//Space 2
	//If type is greater than this it is able to draw
	BLOCK_DRAWABLES		= (1<<9),						// 0000-0010
	BLOCK_COLLIDABLE	= (1<<9),

	//Space 3
	BLOCK_TYPE_LIMITER	= (1<<9|1<<8),					// 0000-0011

	// Space 4 0000-0100
	BLOCK_TYPE_WIN		= (1<<10)

// Space 5 0000-0101
// 1<<10|1<<8
// Space 6 0000-0110
// 1<<10|1<<9
// Space 7 0000-0111
// 1<<10|1<<9|1<<8
};

//20 spaces reserved for solid blocks
enum eSolidTypes {
	//If type is greater than this it is a solid type
	BLOCK_SOLIDS = (1<<11),								// 0000-1000
	//Space 1
		BLOCK_TYPE_DIRT		= (1<<11|1<<8),					// 0000-1001
	//Space 2
		BLOCK_TYPE_ROCK		= (1<<11|1<<9),					// 0000-1010
	//Space 3
		BLOCK_TYPE_WOOD		= (1<<11|1<<9|1<<8),			// 0000-1011
	//Space 4
		BLOCK_TYPE_GRASS	= (1<<11|1<<10),				// 0000-1100
	//Space 5
		BLOCK_TYPE_TREE		= (1<<11|1<<10|1<<8),			// 0000-1101
	//Space 6
		BLOCK_TYPE_LEAF		= (1<<11|1<<10|1<<9),			// 0000-1110
	// Space 7 
		BLOCK_TYPE_ORE1		= (1<<11|1<<10|1<<9|1<<8)		// 0000-1111
// Space 8 0001-0000
// Space 9 0001-0001
// Space 10 0001-0010
// Space 11 0001-0010
// Space 12 0001-0011
// Space 13 0001-0100
// Space 14 0001-0101
// Space 15 0001-0110
// Space 16 0001-0111
// Space 17 0001-1000
// Space 18 0001-1001
// Space 19 0001-1010
// Space 20 0001-1011
};


//5 spaces reserved for liquid blocks

enum eLiquidTypes {
	//If type is greater than this it is a liquid type
	BLOCK_LIQUIDS = (1<<12|1<<11|1<<10),				// 0001-1100
	//Space 1
		BLOCK_TYPE_WATER	= (1<<12|1<<11|1<<10|1<<8)		// 0001-1101
//Space 2 0001-1110
//Space 3 0001-1111
//Space 4 0010-0000
//Space 5 0010-0001
};


//Flips all the bits on for type
// Used to select a section of the int so it can be analyzed
#define BLOCK_TYPE_MASK		SECOND_BYTE_MASK




/** TRAIT TYPES **\
\**	Bit #3	    **/
/*#1 0000-0000  #2 0000-0000  #3 0000-0000  #4 0000-0000
									 ^*/
//Bit 3
//1<<16 = first bit
//1<<23 = last bit
//Trait Types

enum eTraits {
	//Air
	BLOCK_TRAIT_DIRUP		= (1<<16),					// 0000-0001
	BLOCK_TRAIT_DIRDOWN		= (1<<17),					// 0000-0010
	BLOCK_TRAIT_DIRLEFT		= (1<<17|1<<16),			// 0000-0011
	BLOCK_TRAIT_DIRRIGHT	= (1<<18),					// 0000-0100

	//Dirt
	BLOCK_TRAIT_WEIGHT		= (1<<18|1<<16),			// 0000-0101

	//Rock
	BLOCK_TRAIT_DENSITY		= (1<<18|1<<17),			// 0000-0110

	//Water
	BLOCK_TRAIT_FLOWLENGTH1	= (1<<18|1<<17|1<<16),		// 0000-0111
	BLOCK_TRAIT_FLOWLENGTH2	= (1<<19),					// 0000-1000
	BLOCK_TRAIT_FLOWLENGTH3	= (1<<19|1<<16),			// 0000-1001
	BLOCK_TRAIT_FLOWLENGTH4	= (1<<19|1<<17),			// 0000-1010

	//Limiter Block
	BLOCK_TRAIT_UNBREAKABLE = (1<<19|1<<18),
};


//Wood
//Uses dirt for now

//Flips all the bits on for trait
#define BLOCK_TRAIT_MASK		THIRD_BYTE_MASK





/** TRAIT POWERS **\
\**	Bit #4		 **/
/*#1 0000-0000  #2 0000-0000  #3 0000-0000  #4 0000-0000
												   ^*/
//Bit 4
//1<<24 = first bit
//1<<31 = last bit
//Trait Powers

enum eTraitPow {
	BLOCK_TRAIT_POW_POWER1			= (1<<24),				// 0000-0001
	BLOCK_TRAIT_POW_POWER2			= (1<<25),				// 0000-0010
	BLOCK_TRAIT_POW_POWER3			= (1<<25|1<<24),		// 0000-0011
	BLOCK_TRAIT_POW_POWER4			= (1<<26),				// 0000-0100
	BLOCK_TRAIT_POW_POWER5			= (1<<26|1<<24),		// 0000-0101
	BLOCK_TRAIT_POW_POWER6			= (1<<26|1<<25),		// 0000-0110
	BLOCK_TRAIT_POW_POWER7			= (1<<26|1<<25|1<<24),	// 0000-0111
	BLOCK_TRAIT_POW_POWER8			= (1<<27),				// 0000-1000
	BLOCK_TRAIT_POW_POWER9			= (1<<27|1<<24),		// 0000-1001
	BLOCK_TRAIT_POW_POWER10			= (1<<27|1<<25)			// 0000-1010
};


//Flips all the bits on for trait power
#define BLOCK_TRAIT_POW_MASK		FOURTH_BYTE_MASK

enum eDefaults {
	DEFAULT_AIR_BLOCK		= (unsigned int)(BLOCK_TYPE_AIR|BLOCK_TRAIT_DIRDOWN|BLOCK_TRAIT_POW_POWER1),
	DEFAULT_DIRT_BLOCK		= (unsigned int)(BLOCK_TYPE_DIRT|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER1),
	DEFAULT_GRASS_BLOCK		= (unsigned int)(BLOCK_TYPE_GRASS|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER1),
	DEFAULT_ROCK_BLOCK		= (unsigned int)(BLOCK_TYPE_ROCK|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER5),
	DEFAULT_ORE1_BLOCK		= (unsigned int)(BLOCK_TYPE_ORE1|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER7),
	DEFAULT_TREE_BLOCK		= (unsigned int)(BLOCK_TYPE_TREE|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER2),
	DEFAULT_LEAF_BLOCK		= (unsigned int)(BLOCK_TYPE_LEAF|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER1),
	LIMITER_BLOCK			= (unsigned int)(BLOCK_TYPE_LIMITER|BLOCK_TRAIT_UNBREAKABLE|BLOCK_TRAIT_POW_POWER10),
	WIN_BLOCK				= (unsigned int)(BLOCK_TYPE_WIN|BLOCK_TRAIT_WEIGHT|BLOCK_TRAIT_POW_POWER1)
};